package com.gpnu7_412.yanzhi.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gpnu7_412.yanzhi.dto.ConciseUserDto;
import com.gpnu7_412.yanzhi.dto.DataStatisticsDto;
import com.gpnu7_412.yanzhi.dto.DynamicDisplayDto;
import com.gpnu7_412.yanzhi.entity.Dynamic;
import com.gpnu7_412.yanzhi.entity.DynamicHanding;
import com.gpnu7_412.yanzhi.entity.User;
import com.gpnu7_412.yanzhi.exception.custom.DataNotFoundException;
import com.gpnu7_412.yanzhi.exception.custom.PermissionDeniedException;
import com.gpnu7_412.yanzhi.exception.custom.SQLExecuteException;
import com.gpnu7_412.yanzhi.mapper.*;
import com.gpnu7_412.yanzhi.service.DynamicService;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author ZZH
 */
@Service
public class DynamicServiceImpl implements DynamicService {
    @Autowired
    private DynamicMapper dynamicMapper;
    @Autowired
    private InterestMapper interestMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private DynamicHandingMapper dynamicHandingMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserDetailMapper userDetailMapper;

    /**
     * 发布动态
     * @param dynamic 动态信息
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean releaseDynamic(Dynamic dynamic) {
        if (dynamic == null) {
            return false;
        }
        if (dynamicMapper.insertDynamic(dynamic) != 1) {
            throw new SQLExecuteException("发布动态失败,请重试或联系管理员");
        }
        if (userDetailMapper.updateDynamicNumByUserId(dynamic.getUserId(), 1) != 1) {
            throw new SQLExecuteException("发布动态失败,请重试或联系管理员");
        }
        return true;
    }

    /**
     * 删除动态
     * @param dynamicId 待删动态ID
     * @param userId 操作用户ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDynamic(Integer dynamicId, Integer userId) {
        if (dynamicId == null || userId == null) {
            return false;
        }
        Dynamic dynamic = dynamicMapper.getDynamicById(dynamicId);
        if (dynamic == null) {
            throw new DataNotFoundException("待删动态不存在");
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new DataNotFoundException("操作用户不存在");
        }
        if ("管理员".equals(user.getPermission()) || dynamic.getUserId().equals(userId)) {
            commentMapper.deleteByDynamicId(dynamicId);
            if (!commentMapper.selectCommentDtoByDynamicId(dynamicId).isEmpty()) {
                throw new SQLExecuteException("删除动态失败，请重试或联系管理员");
            }
            if (dynamicMapper.deleteDynamic(dynamicId) != 1) {
                throw new SQLExecuteException("删除动态失败,请重试或联系管理员");
            }
            if (userDetailMapper.updateDynamicNumByUserId(dynamic.getUserId(), -1) != 1) {
                throw new SQLExecuteException("删除动态失败,请重试或联系管理员");
            }
            return true;
        }
        throw new PermissionDeniedException("权限不足");
    }

    /**
     * 修改动态信息
     * @param dynamic 修改动态信息
     * @param userId 操作用户ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDynamic(Dynamic dynamic, Integer userId) {
        if (dynamic == null || userId == null) {
            return false;
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new DataNotFoundException("操作用户不存在");
        }
        Dynamic selectDynamic = dynamicMapper.getDynamicById(dynamic.getDynamicId());
        if (selectDynamic == null) {
            throw new DataNotFoundException("待修改动态不存在");
        }
        if ("管理员".equals(user.getPermission()) || selectDynamic.getUserId().equals(userId)) {
            if (dynamicMapper.updateDynamic(dynamic) != 1) {
                throw new SQLExecuteException("修改动态失败，请重试或联系管理员");
            }
            return true;
        }
        throw new PermissionDeniedException("权限不足");
    }

    /**
     * 动态点赞
     * @param dynamicId 动态ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean likeDynamic(Integer dynamicId) {
        if (dynamicId == null) {
            return false;
        }
        if (dynamicMapper.likeDynamic(dynamicId) != 1) {
            throw new SQLExecuteException("点赞失败");
        }
        return true;
    }

    /**
     * 动态举报
     * @param dynamicHanding 动态举报信息
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reportDynamic(DynamicHanding dynamicHanding) {
        if (dynamicHanding == null) {
            return false;
        }
        if (dynamicMapper.getDynamicById(dynamicHanding.getDynamicId()) == null) {
            throw new DataNotFoundException("举报动态不存在");
        }
        if (dynamicHandingMapper.insert(dynamicHanding) != 1) {
            throw new SQLExecuteException("举报失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 根据动态ID获取动态展示DTO
     * @param dynamicId 动态ID
     * @return 动态展示DTO
     */
    @Override
    public DynamicDisplayDto getDynamicById(Integer dynamicId) {
        Dynamic dynamic = dynamicMapper.getDynamicById(dynamicId);
        if (dynamic == null) {
            throw new DataNotFoundException("查无此动态");
        }
        User user = userMapper.selectById(dynamic.getUserId());
        return new DynamicDisplayDto(user, dynamic);
    }

    /**
     * 根据用户ID获取该用户发布的动态
     * @param userId 用户ID
     * @return 动态列表
     */
    @Override
    public List<Dynamic> getDynamicByUserId(Integer userId) {
        if (userId == null) {
            return null;
        }
        return dynamicMapper.getDynamicByUserId(userId);
    }

    /**
     * 根据条件分页查询动态
     *
     * @param pageNum  查询页
     * @param pageSize 页面大小
     * @param dynamic  动态信息
     * @return 动态展示DTO
     */
    @Override
    public PageInfo<DynamicDisplayDto> getDynamicsByCondition(Integer pageNum, Integer pageSize, Dynamic dynamic) {
        Integer dynamicId = dynamic.getDynamicId();
        Integer userId = dynamic.getUserId();
        String title;
        if (dynamic.getTitle() == null || dynamic.getTitle().isEmpty()) {
            title = null;
        } else {
            title = "%" + dynamic.getTitle() + "%";
        }
        PageHelper.startPage(pageNum, pageSize);
        List<DynamicDisplayDto> dynamicDisplayDtoList = dynamicMapper.selectDynamicByCondition(dynamicId, userId, title);
        PageInfo<DynamicDisplayDto> pageInfo = new PageInfo<>(dynamicDisplayDtoList, 5);
        return pageInfo;
    }

    @Override
    public List<DataStatisticsDto> getQuantityStatistics(LocalDateTime startDate, LocalDateTime endDate) {
        int days = (int) ChronoUnit.DAYS.between(startDate, endDate) + 1;
        int[] statistics = new int[days];
        List<Dynamic> dynamicList = dynamicMapper.getDynamicByTime(Timestamp.valueOf(startDate), Timestamp.valueOf(endDate));
        for (Dynamic dynamic : dynamicList) {
            statistics[Math.abs((int) ChronoUnit.DAYS.between(startDate, dynamic.getPublishTime().toLocalDateTime()))]++;
        }
        List<DataStatisticsDto> dataStatisticsDtoList = new ArrayList<>();
        LocalDateTime dateTime = startDate;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        for (int statistic : statistics) {
            DataStatisticsDto dataStatisticsDto = new DataStatisticsDto();
            dataStatisticsDto.setItem(dateTime.format(formatter));
            dataStatisticsDto.setTotal(statistic);
            dataStatisticsDtoList.add(dataStatisticsDto);
            dateTime = dateTime.plusDays(1);
        }
        return dataStatisticsDtoList;
    }

    /**
     * 获取所有动态展示信息
     * @return 动态展示DTO
     */
    @Override
    public PageInfo<DynamicDisplayDto> getAllDynamic(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<DynamicDisplayDto> dynamicDisplayDtoList = dynamicMapper.getAllDynamic();
        PageInfo<DynamicDisplayDto> pageInfo = new PageInfo<>(dynamicDisplayDtoList, 5);
        return pageInfo;
    }

    /**
     * 获取所有关注者的动态信息
     * @param userId 用户ID
     * @return 动态展示DTO
     */
    @Override
    public PageInfo<DynamicDisplayDto> getAllAttention(Integer pageNum, Integer pageSize, Integer userId) {
        List<Integer> userIds = interestMapper.selectMyInterestList(userId)
                .stream()
                .map(User::getUserId)
                .toList();
        if (userIds.isEmpty()) {
            return new PageInfo<>(new ArrayList<>(), 5);
        }
        PageHelper.startPage(pageNum, pageSize);
        List<DynamicDisplayDto> dynamicDisplayDtoList = dynamicMapper.getAllAttention(userIds);
        PageInfo<DynamicDisplayDto> pageInfo = new PageInfo<>(dynamicDisplayDtoList, 5);
        return pageInfo;
    }


    /**
     * 根据标题模糊查找动态
     * @param title 标题
     * @return 动态信息DTO
     */
    @Override
    public List<DynamicDisplayDto> getDynamicByTitle(String title) {
        if (title == null || title.isEmpty()) {
            return dynamicMapper.getAllDynamic();
        }
        title = "%" + title + "%";
        return dynamicMapper.getDynamicByTitle(title);
    }


}
